﻿using System.Collections.Generic;
using System.Reflection;
using System.Windows.Forms;
using ExcelTools;
using Microsoft.Office.Interop.Excel;
using Office = Microsoft.Office.Core;

namespace ExcelToolsSampleDocument
{
  // ==================================================================================
  /// <summary>
  /// This class represents the Action page to run the Excel samples.
  /// </summary>
  // ==================================================================================
  partial class SamplesActionPane : UserControl
  {
    private readonly Dictionary<int, SampleMethod> _SampleIndex = 
      new Dictionary<int, SampleMethod>();

    #region Lifecycle methods

    // --------------------------------------------------------------------------------
    /// <summary>
    /// Initializes the action page.
    /// </summary>
    // --------------------------------------------------------------------------------
    public SamplesActionPane()
    {
      InitializeComponent();
      DiscoverSamples();
    }

    #endregion

    #region Public properties

    // --------------------------------------------------------------------------------
    /// <summary>
    /// Gets the workbook this action pane is bound to.
    /// </summary>
    // --------------------------------------------------------------------------------
    public ExcelWorkbook Workbook
    {
      get { return Globals.Workbook; }  
    }

    #endregion

    #region SampleMethod type

    // --------------------------------------------------------------------------------
    /// <summary>
    /// This class is responsible for storing information about sample methods.
    /// </summary>
    // --------------------------------------------------------------------------------
    private class SampleMethod
    {
      public readonly string Name;
      public readonly string Description;
      public readonly MethodInfo Method;

      public SampleMethod(string name, string description, MethodInfo method)
      {
        Name = name;
        Description = description;
        Method = method;
      }
    }

    #endregion

    #region Sample discovery

    // --------------------------------------------------------------------------------
    /// <summary>
    /// Collects information about sample methods.
    /// </summary>
    // --------------------------------------------------------------------------------
    private void DiscoverSamples()
    {
      _SampleIndex.Clear();
      int counter = 0;
      foreach (MethodInfo mi in GetType().GetMethods(BindingFlags.Instance | BindingFlags.NonPublic))
      {
        object[] attrs = mi.GetCustomAttributes(typeof (SampleAttribute), false);
        if (attrs.Length > 0)
        {
          SampleAttribute sampleAttr = attrs[0] as SampleAttribute;
          if (sampleAttr != null)
          {
            SampleMethod sampleMethod = new SampleMethod(sampleAttr.Name, sampleAttr.Description, mi);
            _SampleIndex.Add(counter++, sampleMethod);
            SamplesListBox.Items.Add(sampleMethod.Name);
          }
        }
      }
    }

    #endregion

    #region Sample methods

    [Sample("Display workbook properties", "Displays workbook properties in the active sheet.")]
    private void DisplayWorkbookProperties()
    {
      Workbook.Worksheets.Add();
      ExcelWorksheet sheet3 = Workbook.Worksheets.AddBefore(2);
      ExcelWorksheet sheet4 = Workbook.Worksheets.AddAfter(3);
      Workbook.Worksheets.AddBefore(sheet4);
      ExcelWorksheet sheet6 = Workbook.Worksheets.AddAfter(sheet3);
      sheet4.Activate();
      sheet3.CopyBefore(5);
      sheet4.CopyBefore(sheet6);
      
      Range range = Globals.ThisWorkbook.ThisApplication.Cells[1, 1] as Range;
      range.set_Value(XlRangeValueDataType.xlRangeValueDefault, Workbook.Name);
      range = Globals.ThisWorkbook.ThisApplication.Cells[2, 1] as Range;
      range.set_Value(XlRangeValueDataType.xlRangeValueDefault, Workbook.Worksheets[1].Name);
      range = Globals.ThisWorkbook.ThisApplication.Cells[3, 1] as Range;
      range.set_Value(XlRangeValueDataType.xlRangeValueDefault, Workbook.ActiveSheet.Name);
    }

    [Sample("Sample2", "Sample 2 Description")]
    private void Sample2()
    {
      MessageBox.Show("Sample2");
    }

    [Sample("Sample3", "Sample 3 Description")]
    private void Sample3()
    {
      MessageBox.Show("Sample3");
    }

    #endregion

    #region Private event methods

    // --------------------------------------------------------------------------------
    /// <summary>
    /// A new sample is selected.
    /// </summary>
    // --------------------------------------------------------------------------------
    private void SamplesListBox_SelectedIndexChanged(object sender, System.EventArgs e)
    {
      if (SamplesListBox.SelectedIndex >= 0)
      {
        SampleMethod sampleMethod = _SampleIndex[SamplesListBox.SelectedIndex];
        DescriptionBox.Text = sampleMethod.Description;
      }
    }

    // --------------------------------------------------------------------------------
    /// <summary>
    /// Sample is started
    /// </summary>
    // --------------------------------------------------------------------------------
    private void RunButton_Click(object sender, System.EventArgs e)
    {
      if (SamplesListBox.SelectedIndex >= 0)
      {
        SampleMethod sampleMethod = _SampleIndex[SamplesListBox.SelectedIndex];
        sampleMethod.Method.Invoke(this, new object[] {});
      }
    }

    #endregion
  }
}
